#ifndef _L_BV_TREE_120118_NORMAL_CONE_H
#define _L_BV_TREE_120118_NORMAL_CONE_H

#include <ltypes.h>
#include <lmacros.h>
#include <lvectors.h>
#include <lmath.h>
#include <ltriMesh.h>

LLIB_BEGIN
namespace geom {

/* The normal cone class : for self-collision culling */
class NormalCone {
public:
    /* The default constructor */
    NormalCone() {}

    /* The constructor with base data */
    NormalCone(const Vec3f& direction, Float angle) : _direction(direction), _angle(angle) {}

    /* The constructor with single triangle face */
    NormalCone(const MeshFace& tri) : _direction(tri.GetNormal()), _angle(math::EPS_F) { }

    /* Update normal cone using base data */
    inline void Update(const Vec3f& direction, Float angle) { _direction = direction; _angle = angle; }

    /* Update normal cone using single triangle face */
    void Update(const MeshFace& tri) { _direction = tri.GetNormal(); _angle = math::EPS_F; }

    /* Merge */
    inline NormalCone Merge(const NormalCone& another) const { return Merge(*this, another); }
    static NormalCone Merge(const NormalCone& first, const NormalCone& second);

    /* Validate */
    inline Boolean Validate() const { return _angle < math::PI_2; }
    inline static Boolean Validate(const NormalCone& nc) { return nc._angle < math::PI_2; }

private:
    /* The direction vector, note: it must be a normal vector */
    Vec3f _direction;

    /* The angle */
    Float _angle;

};

} // end of namespace geom
LLIB_END

#endif
